package com.xnx.bincker.leader.service.impl;

import com.xnx.bincker.leader.dao.AuthorityRepository;
import com.xnx.bincker.leader.dao.MenuRepository;
import com.xnx.bincker.leader.domain.Authority;
import com.xnx.bincker.leader.domain.Menu;
import com.xnx.bincker.leader.domain.Role;
import com.xnx.bincker.leader.service.MenuService;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MenuServiceImpl extends BasicServiceImpl<Menu, String> implements MenuService {
    private final MenuRepository menuRepository;
    private final AuthorityRepository authorityRepository;

	MenuServiceImpl(
            MenuRepository repository,
            AuthorityRepository authorityRepository) {
		this.menuRepository = repository;
		this.authorityRepository = authorityRepository;
	}

    /**
     * 查询角色菜单
     * @param roles 角色列表
     */
	public List<Menu> queryMenuListByRoleCode(Collection<Role> roles){
        List<Menu> menuList = new LinkedList<>(menuRepository.queryRoleMenuList(roles.stream().map(Role::toString).collect(Collectors.toList())));
        menuList.forEach(item->item.setChildren(new ArrayList<>()));
        Iterator<Menu> menuIterator = menuList.iterator();
        while (menuIterator.hasNext()){
            Menu menu = menuIterator.next();
            Menu parent = menu.getParent();
            if(parent == null) continue;
            for (Menu m : menuList) {
                if(m.equals(parent)){
                    m.getChildren().add(menu);
                    menuIterator.remove();
                    break;
                }
            }
        }
	    return menuList;
    }

    /**
     * 删除时解除权限的关联
     */
    public void deleteInBatch(Collection<Menu> menus) {
        if(menus.isEmpty()) return ;
	    List<Authority> authorityList = authorityRepository.findAll(((root, criteriaQuery, criteriaBuilder) -> {
	        CriteriaBuilder.In<Menu> authorityIn = criteriaBuilder.in(root.get("parentMenu"));
	        menus.forEach(authorityIn::value);
	        return criteriaBuilder.and(authorityIn);
        }));
	    authorityList.forEach(authority -> authority.setParentMenu(null));
	    authorityRepository.saveAll(authorityList);
	    authorityRepository.flush();
        super.deleteInBatch(menus);
    }
}
